package com.zhaokuner.parentstarter.utils;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
import java.util.function.Supplier;

/**
 * 类描述:锁定资源并发量
 *
 * @author 赵希坤 zhaoxikun
 * @date 2020/12/22 10:19
 */
public class SemaphoreUtil {

    private ConcurrentHashMap<String, SemaphoreUtil> semaphoreMap = new ConcurrentHashMap<>(8);

    /**
     * 方法描述：更加key 生成不同的信号量
     *
     * @param key
     * @param permits
     * @return com.lenovo.css.mycommon.utils.SemaphoreUtil
     * @author 赵希坤
     * @date 2020/12/22 10:49
     */
    public SemaphoreUtil get(String key, int permits) {
        SemaphoreUtil semaphoreUtil = semaphoreMap.get(key);
        if (null == semaphoreUtil) {
            semaphoreUtil = new SemaphoreUtil(permits);
            SemaphoreUtil temp = semaphoreMap.putIfAbsent(key, semaphoreUtil);
            if (null != temp) {
                semaphoreUtil = temp;
            }
        }
        return semaphoreUtil;
    }


    private Semaphore semaphore;

    /**
     * 方法描述： 非公平 默认设置 int permits 20
     *
     * @author 赵希坤
     * @date 2020/12/22 10:24
     */
    public SemaphoreUtil() {
        semaphore = new Semaphore(20);
    }

    /**
     * 方法描述：非公平
     *
     * @param permits
     * @author 赵希坤
     * @date 2020/12/22 10:24
     */
    public SemaphoreUtil(int permits) {
        semaphore = new Semaphore(permits);
    }

    /**
     * 方法描述：获取到信号量 执行 supplier 否则，返回null
     *
     * @param supplier
     * @return T
     * @author 赵希坤
     * @date 2020/12/22 10:54
     */
    public <T> T tryAcquire(Supplier<T> supplier) {
        if (null != supplier) {
            boolean has = false;
            try {
                has = semaphore.tryAcquire();
                if (has) {
                    return supplier.get();
                }
            } finally {
                if (has) {
                    semaphore.release();
                }
            }
        }
        return null;
    }


}
